﻿using System.ComponentModel;
using System.Globalization;

namespace System
{
    /// <summary>
    /// 包含了与日期相关的一些常用扩展方法
    /// </summary>
    [EditorBrowsable(EditorBrowsableState.Never)]
    public static class DateTimeExtensions
    {
        const int EveningEnds = 2;
        const int MorningEnds = 12;
        const int AfternoonEnds = 6;
        static readonly DateTime Date1970 = new DateTime(1970, 1, 1);

        #region Second 秒

        /// <summary>
        /// 将时间精确到毫秒
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DateTime ToTrimMilliSecond(this DateTime dt)
        {
            var ticks = dt.Ticks;
            ticks -= ticks % 10000;
            return new DateTime(ticks);
        }

        /// <summary>
        /// 将时间精确到秒
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DateTime TrimToSecond(this DateTime dt)
        {
            var ticks = dt.Ticks;
            ticks -= ticks % (10000 * 1000);
            return new DateTime(ticks);
        }

        #endregion Second 秒

        #region Minute 分

        /// <summary>
        /// 将时间精确到分钟
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DateTime ToTrimMinute(this DateTime dt)
        {
            var ticks = dt.Ticks;
            ticks -= ticks % (10000 * 1000 * 60);
            return new DateTime(ticks);
        }

        #endregion Minute 分

        #region Hour 时

        /// <summary>
        /// 将时间精确到小时
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DateTime ToTrimHour(this DateTime dt)
        {
            var ticks = dt.Ticks;
            ticks -= ticks % (10000L * 1000 * 60 * 60);
            return new DateTime(ticks);
        }

        #endregion Hour 时

        #region Day 日

        #region Unix Epoch 新纪元时间
        /// <summary>
        /// 	Get milliseconds of UNIX area. This is the milliseconds since 1/1/1970
        /// </summary>
        /// <param name = "datetime">Up to which time.</param>
        /// <returns>number of milliseconds.</returns>
        /// <remarks>
        /// 	Contributed by blaumeister, http://www.codeplex.com/site/users/view/blaumeiser
        /// </remarks>
        public static long GetMillisecondsSince1970(this DateTime datetime)
        {
            var ts = datetime.Subtract(Date1970);
            return (long)ts.TotalMilliseconds;
        }

        /// <summary>
        /// Get milliseconds of UNIX area. This is the milliseconds since 1/1/1970
        /// </summary>
        /// <param name="dateTime">The date time.</param>
        /// <returns></returns>
        /// <remarks>This is the same as GetMillisecondsSince1970 but more descriptive</remarks>
        public static long ToUnixEpoch(this DateTime dateTime)
        {
            return GetMillisecondsSince1970(dateTime);
        }
        #endregion //Unix Epoch 新纪元时间

        #region SetTime 设置时间

        /// <summary>
        /// 	Sets the time on the specified DateTime value.
        /// </summary>
        /// <param name = "date">The base date.</param>
        /// <param name = "hours">The hours to be set.</param>
        /// <param name = "minutes">The minutes to be set.</param>
        /// <param name = "seconds">The seconds to be set.</param>
        /// <returns>The DateTime including the new time value</returns>
        public static DateTime SetTime(this DateTime date, int hours, int minutes, int seconds)
        {
            return date.SetTime(new TimeSpan(hours, minutes, seconds));
        }

        /// <summary>
        /// 	Sets the time on the specified DateTime value.
        /// </summary>
        /// <param name = "date">The base date.</param>
        /// <param name="hours">The hour</param>
        /// <param name="minutes">The minute</param>
        /// <param name="seconds">The second</param>
        /// <param name="milliseconds">The millisecond</param>
        /// <returns>The DateTime including the new time value</returns>
        /// <remarks>Added overload for milliseconds - jtolar</remarks>
        public static DateTime SetTime(this DateTime date, int hours, int minutes, int seconds, int milliseconds)
        {
            return date.SetTime(new TimeSpan(0, hours, minutes, seconds, milliseconds));
        }

        /// <summary>
        /// 	Sets the time on the specified DateTime value.
        /// </summary>
        /// <param name = "date">The base date.</param>
        /// <param name = "time">The TimeSpan to be applied.</param>
        /// <returns>
        /// 	The DateTime including the new time value
        /// </returns>
        public static DateTime SetTime(this DateTime date, TimeSpan time)
        {
            return date.Date.Add(time);
        }
        #endregion //SetTime

        #region TimeZoneInfo 时区转换
        /// <summary>
        /// 	Converts a DateTime into a DateTimeOffset using the local system time zone.
        /// </summary>
        /// <param name = "localDateTime">The local DateTime.</param>
        /// <returns>The converted DateTimeOffset</returns>
        public static DateTimeOffset ToDateTimeOffset(this DateTime localDateTime)
        {
            return localDateTime.ToDateTimeOffset(null);
        }

        /// <summary>
        /// 	Converts a DateTime into a DateTimeOffset using the specified time zone.
        /// </summary>
        /// <param name = "localDateTime">The local DateTime.</param>
        /// <param name = "localTimeZone">The local time zone.</param>
        /// <returns>The converted DateTimeOffset</returns>
        public static DateTimeOffset ToDateTimeOffset(this DateTime localDateTime, TimeZoneInfo localTimeZone)
        {
            localTimeZone = (localTimeZone ?? TimeZoneInfo.Local);

            if (localDateTime.Kind != DateTimeKind.Unspecified)
                localDateTime = new DateTime(localDateTime.Ticks, DateTimeKind.Unspecified);

            return TimeZoneInfo.ConvertTimeToUtc(localDateTime, localTimeZone);
        }
        #endregion //TimeZoneInfo 时区转换

        /// <summary>
        /// 获得两个日期之间的天数间隔
        /// </summary>
        /// <param name="beginDate"></param>
        /// <param name="endDate"></param>
        /// <returns></returns>
        public static double ToDaySpan(this DateTime beginDate, DateTime endDate)
        {
            return (endDate.Date - beginDate.Date).TotalDays;
        }

        /// <summary>
        /// 将时间精确到天
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DateTime ToTrimDay(this DateTime dt)
        {
            var ticks = dt.Ticks;
            ticks -= ticks % (10000L * 1000 * 60 * 60 * 24);
            return new DateTime(ticks);
        }

        /// <summary>
        /// 根据日期获取本日的开始时间
        /// </summary>
        /// <param name="value">任意时间</param>
        /// <returns>2001-01-01 00:00:00</returns>
        public static DateTime ToDayStart(this DateTime dateTime)
        {
            return dateTime.Date;
        }

        /// <summary>
        /// 根据日期获取本日的结束时间
        /// </summary>
        /// <param name="value">任意时间</param>
        /// <returns>2001-01-01 23:59:59</returns>
        public static DateTime ToDayEnd(this DateTime dateTime)
        {
            //返回日期加一天减一秒
            return dateTime.Date.AddDays(1).AddSeconds(-1);
        }

        ///<summary>
        ///	获取一天中的时间所在期间
        /// Return a period "Morning", "Afternoon", or "Evening"
        ///</summary>
        ///<param name = "date">The date.</param>
        ///<returns>The period "morning", "afternoon", or "evening"</returns>
        /// <remarks>
        /// 	Contributed by Michael T, http://about.me/MichaelTran
        /// </remarks>
        public static string GetPeriodOfDay(this DateTime date)
        {
            var hour = date.Hour;
            if (hour < EveningEnds)
                return "evening";
            if (hour < MorningEnds)
                return "morning";
            return hour < AfternoonEnds ? "afternoon" : "evening";
        }

        /// <summary>
        /// Gets a DateTime representing Next Day
        /// </summary>
        /// <param name="date">The current day</param>
        /// <returns></returns>
        public static DateTime Tomorrow(this DateTime date)
        {
            return date.AddDays(1);
        }

        /// <summary>
        /// Gets a DateTime representing Previous Day
        /// </summary>
        /// <param name="date">The current day</param>
        /// <returns></returns>
        public static DateTime Yesterday(this DateTime date)
        {
            return date.AddDays(-1);
        }

        /// <summary>
        /// 当天最晚时间
        /// Returns the date at 23:59.59.999 for the specified DateTime
        /// </summary>
        /// <param name="date">The DateTime to be processed</param>
        /// <returns>The date at 23:50.59.999</returns>
        public static DateTime EndOfDay(this DateTime date)
        {
            return date.SetTime(23, 59, 59, 999);
        }

        /// <summary>
        /// 当天中午
        /// Returns the date at 12:00:00 for the specified DateTime
        /// </summary>
        /// <param name="time">The current date</param>
        public static DateTime Noon(this DateTime time)
        {
            return time.SetTime(12, 0, 0);
        }

        /// <summary>
        /// 当天最早时间
        /// Returns the date at 00:00:00 for the specified DateTime
        /// </summary>
        /// <param name="time">The current date</param>
        public static DateTime Midnight(this DateTime time)
        {
            return time.SetTime(0, 0, 0, 0);
        }

       
        #endregion Day 日

        #region Week 周

        #region 根据日期获取本周是本年的第几周
        /// <summary>
        /// Gets the week number for a provided date time value based on a specific culture.
        /// </summary>
        /// <param name="dateTime">The date time.</param>
        /// <param name="culture">Specific culture</param>
        /// <returns>The week number</returns>
        /// <remarks>
        ///     modified by jtolar to implement culture settings
        /// </remarks>
        public static int GetWeekOfYear(this DateTime dateTime, CultureInfo culture)
        {
            var calendar = culture.Calendar;
            var dateTimeFormat = culture.DateTimeFormat;

            return calendar.GetWeekOfYear(dateTime, dateTimeFormat.CalendarWeekRule, dateTimeFormat.FirstDayOfWeek);
        }

        /// <summary>
        /// 根据日期获取本周是本年的第几周
        /// Gets the week number for a provided date time value based on the current culture settings. 
        /// Uses CurrentCulture from ExtensionMethodSetting
        /// </summary>
        /// <param name="dateTime">The date time.</param>
        /// <returns>The week number</returns>
        /// <remarks>
        ///     modified by jtolar to implement culture settings
        /// </remarks>
        public static int GetWeekOfYear(this DateTime dateTime)
        {
            return GetWeekOfYear(dateTime, CultureInfo.CurrentCulture);
        }
        #endregion 根据日期获取本周是本年的第几周

        #region 根据日期获取本周的星期一

        /// <summary>
        /// 根据日期获取本周的星期一
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DateTime ToWeekStart(this DateTime dateTime)
        {
            return dateTime.ToWeekStart(CultureInfo.CurrentCulture);
        }

        /// <summary>
        /// 	Gets the first day of the week using the specified culture.
        /// </summary>
        /// <param name = "date">The date.</param>
        /// <param name = "cultureInfo">The culture to determine the first weekday of a week.</param>
        /// <returns>The first day of the week</returns>
        public static DateTime ToWeekStart(this DateTime date, CultureInfo cultureInfo)
        {
            cultureInfo = (cultureInfo ?? CultureInfo.CurrentCulture);

            var firstDayOfWeek = cultureInfo.DateTimeFormat.FirstDayOfWeek;
            while (date.DayOfWeek != firstDayOfWeek)
                date = date.AddDays(-1);

            return date;
        }
        #endregion 根据日期获取本周的星期一

        #region 根据日期获取本周的星期几
        /// <summary>
        /// 	Gets the next occurence of the specified weekday within the current week using the current culture.
        /// </summary>
        /// <param name = "date">The base date.</param>
        /// <param name = "weekday">The desired weekday.</param>
        /// <returns>The calculated date.</returns>
        /// <example>
        /// 	<code>
        /// 		var thisWeeksMonday = DateTime.Now.GetWeekday(DayOfWeek.Monday);
        /// 	</code>
        /// </example>
        /// <remarks>
        ///     modified by jtolar to implement culture settings
        /// </remarks>
        public static DateTime ToWeeksWeekday(this DateTime date, DayOfWeek weekday)
        {
            return date.ToWeeksWeekday(weekday, CultureInfo.CurrentCulture);
        }

        /// <summary>
        /// 	Gets the next occurence of the specified weekday within the current week using the specified culture.
        /// </summary>
        /// <param name = "date">The base date.</param>
        /// <param name = "weekday">The desired weekday.</param>
        /// <param name = "cultureInfo">The culture to determine the first weekday of a week.</param>
        /// <returns>The calculated date.</returns>
        /// <example>
        /// 	<code>
        /// 		var thisWeeksMonday = DateTime.Now.GetWeekday(DayOfWeek.Monday);
        /// 	</code>
        /// </example>
        public static DateTime ToWeeksWeekday(this DateTime date, DayOfWeek weekday, CultureInfo cultureInfo)
        {
            var firstDayOfWeek = date.ToWeekStart(cultureInfo);
            return firstDayOfWeek.ToNextWeekday(weekday);
        }

        /// <summary>
        /// 	获取本周的某天
        /// 	Gets the next occurence of the specified weekday.
        /// </summary>
        /// <param name = "date">The base date.</param>
        /// <param name = "weekday">The desired weekday.</param>
        /// <returns>The calculated date.</returns>
        /// <example>
        /// 	<code>
        /// 		var lastMonday = DateTime.Now.GetNextWeekday(DayOfWeek.Monday);
        /// 	</code>
        /// </example>
        public static DateTime ToNextWeekday(this DateTime date, DayOfWeek weekday)
        {
            while (date.DayOfWeek != weekday)
                date = date.AddDays(1);
            return date;
        }


        #endregion //根据日期获取本周的星期几

        #region 根据日期获取本周的星期天

        /// <summary>
        /// 根据日期获取本周的星期一
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static DateTime ToWeekEnd(this DateTime dateTime)
        {
            return dateTime.ToWeekEnd(CultureInfo.CurrentCulture);
        }

        /// <summary>
        /// 	Gets the last day of the week using the specified culture.
        /// </summary>
        /// <param name = "date">The date.</param>
        /// <param name = "cultureInfo">The culture to determine the first weekday of a week.</param>
        /// <returns>The first day of the week</returns>
        public static DateTime ToWeekEnd(this DateTime date, CultureInfo cultureInfo)
        {
            return date.ToWeekStart(cultureInfo).AddDays(6);
        }
        #endregion 根据日期获取本周的星期天

        #region 根据年份和周数获取某周第一天

        /// <summary>
        /// 根据年份和周数获取某周第一天
        /// </summary>
        /// <param name="year">年份</param>
        /// <param name="weekOfYear">第几周</param>
        /// <returns></returns>
        public static DateTime ToWeekStart(int year, int weekOfYear)
        {
            DateTime time = new DateTime(year, 1, 1);
            int num = CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek - time.DayOfWeek;
            DateTime dateTime = time.AddDays((double)num);
            int weekOfYear2 = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(time, CultureInfo.CurrentCulture.DateTimeFormat.CalendarWeekRule, CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek);
            if (weekOfYear2 <= 1)
            {
                weekOfYear--;
            }
            return dateTime.AddDays((double)(weekOfYear * 7));
        }

        #endregion 根据年份和周数获取某周第一天

        #region 获取几周后的同一时间
        /// <summary>
        /// 	Adds the specified amount of weeks (=7 days gregorian calendar) to the passed date value.
        /// </summary>
        /// <param name = "date">The origin date.</param>
        /// <param name = "value">The amount of weeks to be added.</param>
        /// <returns>The enw date value</returns>
        public static DateTime AddWeeks(this DateTime date, int value)
        {
            return date.AddDays(value * 7);
        }
        #endregion //获取几周后的同一时间

        #endregion Week 周

        #region Month 月

        /// <summary>
        /// 获得两个日期之间的月数
        /// </summary>
        /// <param name="beginDate"></param>
        /// <param name="endDate"></param>
        /// <returns></returns>
        public static double ToBetweenMonthes(this DateTime beginDate, DateTime endDate)
        {
            var months = 0.0;
            for (; beginDate <= endDate; beginDate = beginDate.AddMonths(1))
            {
                months++;
            }
            months = months - (beginDate - endDate).TotalDays / DateTime.DaysInMonth(endDate.Year, endDate.Month);
            return months;
        }

        /// <summary>
        /// 根据日期获取本月的完整名称
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static string ToMonthName(this DateTime dateTime)
        {
            return CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(dateTime.Month);
        }

        /// <summary>
        /// 根据日期获取本月的缩写名称
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static string ToShortMonthName(this DateTime dateTime)
        {
            return CultureInfo.CurrentCulture.DateTimeFormat.GetAbbreviatedMonthName(dateTime.Month);
        }

        /// <summary>
        /// 根据日期获取下个月的完整名称
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static string ToNextMonthName(this DateTime dateTime)
        {
            return new DateTime(dateTime.Year, dateTime.Month, 1).AddMonths(1).ToMonthName();
        }

        /// <summary>
        /// 根据日期获取本月的开始时间
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static DateTime ToMonthStart(this DateTime dateTime)
        {
            return new DateTime(dateTime.Year, dateTime.Month, 1);
        }

        /// <summary>
        /// 根据日期获取本月的结束时间
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static DateTime ToMonthEnd(this DateTime dateTime)
        {
            return new DateTime(dateTime.Year, dateTime.Month, DateTime.DaysInMonth(dateTime.Year, dateTime.Month));
        }

        /// <summary>
        ///  返回本月的天数	Returns the number of days in the month of the provided date.
        /// </summary>
        /// <param name = "date">The date.</param>
        /// <returns>The number of days.</returns>
        public static int CountDaysOfMonth(this DateTime date)
        {
            var nextMonth = date.AddMonths(1);
            return new DateTime(nextMonth.Year, nextMonth.Month, 1).AddDays(-1).Day;
        }

        /// <summary>
        /// 返回当月的天数
        /// </summary>
        /// <param name="year">年份</param>
        /// <param name="month">月份</param>
        /// <returns></returns>
        public static int CountDaysOfMonth(int year,int month)
        {
            if (month < 1) month = 1;
            if (month > 12) month = 12;
            var nextMonth = new DateTime(year, month, 1).AddMonths(1);
            return nextMonth.AddDays(-1).Day;
        }
        #endregion Month 月

        #region Year 年

        #region 根据日期获取本年的开始时间

        /// <summary>
        /// 根据日期获取本年的开始时间
        /// </summary>
        /// <param name="value">任意时间</param>
        /// <returns>2001-01-01 00:00:00</returns>
        public static DateTime ToYearStart(this DateTime dateTime)
        {
            //根据年、月重新创建日期
            return new DateTime(dateTime.Year, 1, 1);
        }

        #endregion 根据日期获取本年的开始时间

        #region 根据日期获取本年的结束时间

        /// <summary>
        /// 根据日期获取本年的结束时间
        /// </summary>
        /// <param name="value">任意时间</param>
        /// <returns>2001-12-31 23:59:59</returns>
        public static DateTime ToYearEnd(this DateTime dateTime)
        {
            //根据年、月重新创建日期
            DateTime yearStart = new DateTime(dateTime.Year, 1, 1);
            //创建结束日期
            return new DateTime(dateTime.Year, 1, 1).AddYears(1).AddSeconds(-1);
        }

        #endregion 根据日期获取本年的结束时间

        #region 根据出生日期计算年龄
        /// <summary>
        /// 	Calculates the age based on today.
        /// </summary>
        /// <param name = "dateOfBirth">The date of birth.</param>
        /// <returns>The calculated age.</returns>
        public static int CalculateAge(this DateTime dateOfBirth)
        {
            return CalculateAge(dateOfBirth, DateTime.Now.Date);
        }

        /// <summary>
        /// 	Calculates the age based on a passed reference date.
        /// </summary>
        /// <param name = "dateOfBirth">The date of birth.</param>
        /// <param name = "referenceDate">The reference date to calculate on.</param>
        /// <returns>The calculated age.</returns>
        public static int CalculateAge(this DateTime dateOfBirth, DateTime referenceDate)
        {
            var years = referenceDate.Year - dateOfBirth.Year;
            if (referenceDate.Month < dateOfBirth.Month || (referenceDate.Month == dateOfBirth.Month && referenceDate.Day < dateOfBirth.Day))
                --years;
            return years;
        }
        #endregion

        #region 某年有多少天
        ///<summary>
        ///	Get the number of days within that year.
        ///</summary>
        ///<param name = "year">The year.</param>
        ///<returns>the number of days within that year</returns>
        /// <remarks>
        /// 	Contributed by Michael T, http://about.me/MichaelTran
        ///     Modified by JTolar to implement Culture Settings
        /// </remarks>
        public static int GetYearDays(int year)
        {
            return GetYearDays(year, CultureInfo.CurrentCulture);
        }

        ///<summary>
        ///	Get the number of days within that year. Uses the culture specified.
        ///</summary>
        ///<param name = "year">The year.</param>
        ///<param name="culture">Specific culture</param>
        ///<returns>the number of days within that year</returns>
        /// <remarks>
        /// 	Contributed by Michael T, http://about.me/MichaelTran
        ///     Modified by JTolar to implement Culture Settings
        /// </remarks>
        public static int GetYearDays(int year, CultureInfo culture)
        {
            var first = new DateTime(year, 1, 1, culture.Calendar);
            var last = new DateTime(year + 1, 1, 1, culture.Calendar);
            return GetBetweenDays(first, last);
        }


        ///<summary>
        ///	Get the number of days within that date year. Allows user to specify culture.
        ///</summary>
        ///<param name = "date">The date.</param>
        ///<param name="culture">Specific culture</param>
        ///<returns>the number of days within that year</returns>
        /// <remarks>
        /// 	Contributed by Michael T, http://about.me/MichaelTran
        ///     Modified by JTolar to implement Culture Settings 
        /// </remarks>
        public static int GetYearDays(this DateTime date)
        {
            return GetYearDays(date.Year, CultureInfo.CurrentCulture);
        }

        ///<summary>
        ///	Get the number of days within that date year. Allows user to specify culture
        ///</summary>
        ///<param name = "date">The date.</param>
        ///<param name="culture">Specific culture</param>
        ///<returns>the number of days within that year</returns>
        /// <remarks>
        /// 	Contributed by Michael T, http://about.me/MichaelTran
        ///     Modified by JTolar to implement Culture Settings 
        /// </remarks>
        public static int GetYearDays(this DateTime date, CultureInfo culture)
        {
            return GetYearDays(date.Year, culture);
        }

        ///<summary>
        /// 获取两个日期之间的天数
        ///	Get the number of days between two dates.
        ///</summary>
        ///<param name = "fromDate">The origin year.</param>
        ///<param name = "toDate">To year</param>
        ///<returns>The number of days between the two years</returns>
        /// <remarks>
        /// 	Contributed by Michael T, http://about.me/MichaelTran
        /// </remarks>
        public static int GetBetweenDays(this DateTime fromDate, DateTime toDate)
        {
            return Convert.ToInt32(toDate.Subtract(fromDate).TotalDays);
        }
        #endregion //某年有多少天

        #endregion Year 年

        #region Convert 转换

        #region 获取某一时间的唯一的长字符串

        /// <summary>
        /// 获取某一时间的唯一的长字符串 yyyyMMddhhmmssFFF
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static string ToLongUniqueString(this DateTime dateTime)
        {
            return string.Format("{0}{1:00}{2:00}{3:00}{4:00}{5:00}{6:000}", dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond);
        }

        #endregion 获取某一时间的唯一的长字符串

        #region 获取某一时间的唯一的短字符串

        /// <summary>
        /// 获取某一时间的唯一的短字符串 yyyyMMddhhmmss
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static string ToShortUniqueString(this DateTime dateTime)
        {
            return string.Format("{0}{1:00}{2:00}{3:00}{4:00}{5:00}", dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dateTime.Second);
        }

        #endregion 获取某一时间的唯一的短字符串

        #region 获取某一时间的日期字符串

        /// <summary>
        /// 获取某一时间的日期字符串 yyyyMMdd
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static string ToDateUniqueString(this DateTime dateTime)
        {
            return string.Format("{0}{1:00}{2:00}", dateTime.Year, dateTime.Month, dateTime.Day);
        }

        #endregion 获取某一时间的日期字符串

        #region 获取某一时间的时间字符串

        /// <summary>
        /// 获取某一时间的时间字符串 hhmmssFFF
        /// </summary>
        /// <param name="dateTime"></param>
        /// <returns></returns>
        public static string ToTimeUniqueString(this DateTime dateTime)
        {
            return string.Format("{0:00}{1:00}{2:00}{3:000}", dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond);
        }

        #endregion 获取某一时间的时间字符串

        #endregion string 字符串

        #region Bool 判断

        #region Compare 比较
        /// <summary>
        /// 	Determines whether the date only part of twi DateTime values are equal.
        /// </summary>
        /// <param name = "date">The date.</param>
        /// <param name = "dateToCompare">The date to compare with.</param>
        /// <returns>
        /// 	<c>true</c> if both date values are equal; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsDateEqual(this DateTime date, DateTime dateToCompare)
        {
            return (date.Date == dateToCompare.Date);
        }

        /// <summary>
        /// 	Determines whether the time only part of two DateTime values are equal.
        /// </summary>
        /// <param name = "time">The time.</param>
        /// <param name = "timeToCompare">The time to compare.</param>
        /// <returns>
        /// 	<c>true</c> if both time values are equal; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsTimeEqual(this DateTime time, DateTime timeToCompare)
        {
            return (time.TimeOfDay == timeToCompare.TimeOfDay);
        }
        #endregion

        #region 周末与工作日
        /// <summary>
        /// 是否是工作日
        /// Returns whether the DateTime falls on a weekday
        /// </summary>
        /// <param name="date">The date to be processed</param>
        /// <returns>Whether the specified date occurs on a weekday</returns>
        public static bool IsWeekDay(this DateTime date)
        {
            return !date.IsWeekend();
        }

        /// <summary>
        /// 是否是周末
        /// 	Indicates whether the specified date is a weekend (Saturday or Sunday).
        /// </summary>
        /// <param name = "date">The date.</param>
        /// <returns>
        /// 	<c>true</c> if the specified date is a weekend; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsWeekend(this DateTime date)
        {
            return date.DayOfWeek.EqualsAny(DayOfWeek.Saturday, DayOfWeek.Sunday);
        }
        #endregion //周末与工作日
     

        /// <summary>
        /// 是否是复活节
        ///     Indicates whether the specified date is Easter in the Christian calendar.
        /// </summary>
        /// <param name="date">Instance value.</param>
        /// <returns>True if the instance value is a valid Easter Date.</returns>
        public static bool IsEaster(this DateTime date)
        {
            int Y = date.Year;
            int a = Y % 19;
            int b = Y / 100;
            int c = Y % 100;
            int d = b / 4;
            int e = b % 4;
            int f = (b + 8) / 25;
            int g = (b - f + 1) / 3;
            int h = (19 * a + b - d - g + 15) % 30;
            int i = c / 4;
            int k = c % 4;
            int L = (32 + 2 * e + 2 * i - h - k) % 7;
            int m = (a + 11 * h + 22 * L) / 451;
            int Month = (h + L - 7 * m + 114) / 31;
            int Day = ((h + L - 7 * m + 114) % 31) + 1;

            DateTime dtEasterSunday = new DateTime(Y, Month, Day);

            return date == dtEasterSunday;
        }

        #region 前面后面
        /// <summary>
        /// 	Indicates whether the date is today.
        /// </summary>
        /// <param name = "dt">The date.</param>
        /// <returns>
        /// 	<c>true</c> if the specified date is today; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsToday(this DateTime dt)
        {
            return (dt.Date == DateTime.Today);
        }

        /// <summary>
        ///  在...之前
        ///     Indicates whether the source DateTime is before the supplied DateTime.
        /// </summary>
        /// <param name="source">The source DateTime.</param>
        /// <param name="other">The compared DateTime.</param>
        /// <returns>True if the source is before the other DateTime, False otherwise</returns>
        public static bool IsBefore(this DateTime source, DateTime other)
        {
            return source.CompareTo(other) < 0;
        }

        /// <summary>
        /// 在....之后
        ///     Indicates whether the source DateTime is before the supplied DateTime.
        /// </summary>
        /// <param name="source">The source DateTime.</param>
        /// <param name="other">The compared DateTime.</param>
        /// <returns>True if the source is before the other DateTime, False otherwise</returns>
        public static bool IsAfter(this DateTime source, DateTime other)
        {
            return source.CompareTo(other) > 0;
        }
        #endregion //前面后面
       
        #endregion //Bool 判断
    }
}